package com.pine.app.module.security.oauth.plugin.impl.loginAttemp;

import com.pine.app.module.security.core.common.AuthConstant;
import com.pine.app.module.security.core.common.enums.ResponseProduceType;
import com.pine.app.module.security.oauth.config.properties.LoginProperties;
import com.pine.app.module.security.core.common.enums.ErrorType;
import com.pine.app.module.security.oauth.exception.AuthenticationException;
import com.pine.app.module.security.oauth.exception.BadCredentialsException;
import com.pine.app.module.security.oauth.plugin.AbstractProcessPlugin;
import com.pine.app.module.security.oauth.plugin.Plugin;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 *  登陆攻击插件
 * @author xiaoyuan
 * @create 2020/3/8 18:06
 **/
@Slf4j
public class LoginAttempPlugin extends AbstractProcessPlugin {

    private LoginAttempService loginAttempService;

    private LoginProperties loginProperty;
    private String username;

    public LoginAttempPlugin ( LoginProperties loginProperty){
        this.loginProperty = loginProperty;

    }

    @Autowired
    public void setLoginAttempService(LoginAttempService loginAttempService) {
        this.loginAttempService = loginAttempService;
    }

    @Override
    public int getOrder() {
        return 20;
    }

    @Override
    public void init() {
        log.info("防登陆攻击插件初始化成功");
    }

    @Override
    public void prepare(HttpServletRequest request, HttpServletResponse response, Object o) throws ServletException, IOException {
      //  log.info("开始执行防登陆攻击插件");
        username = request.getParameter(AuthConstant.username);
        String error_message = "";
        if (StringUtils.isNotEmpty(username) && loginAttempService.isBlocked(username)) {
            error_message = "账户登录错误次数过多，账户已被锁定，请" + loginProperty.getAttemp().getExpire() / (1000 * 60) + "分钟后再次尝试！";
            throw new AuthenticationException(ErrorType.SERVICE_ERROR,error_message,getResponseProduceTypeEnum(),AuthConstant.DEFAULT_LOGIN_PATH,0);
        }

    }

    @Override
    public void complete(HttpServletRequest request, HttpServletResponse response, Object o) {
        if (StringUtils.isNotEmpty(username)) {
            loginAttempService.loginSucceeded(username);
        }
    }

    @Override
    public void exception(HttpServletRequest request, HttpServletResponse response, Exception e) throws ServletException, IOException {
        if (StringUtils.isNotEmpty(username)) {
            loginAttempService.loginFailed(username);
        }
        String message ="";
        if(e instanceof BadCredentialsException){
            int t = 0;
           if (StringUtils.isNotEmpty(username) && !loginAttempService.isBlocked(username)) {
               t = loginProperty.getAttemp().getTimers()-loginAttempService.loginTimes(username);
               message = "账号或密码错误，您还有"+t+"次尝试机会";
           }
           if (StringUtils.isNotEmpty(username) && loginAttempService.isBlocked(username)) {
               message = "账户登录错误次数过多，账户已被锁定，请" + loginProperty.getAttemp().getExpire() / (1000 * 60) + "分钟后再次尝试！";
           }
           throw new AuthenticationException(ErrorType.SERVICE_ERROR,message,getResponseProduceTypeEnum(),AuthConstant.DEFAULT_LOGIN_PATH,t);
       }
        throw new AuthenticationException(ErrorType.SERVICE_ERROR,e.getMessage(),getResponseProduceTypeEnum(),AuthConstant.DEFAULT_LOGIN_PATH,null);
    }

    @Override
    public boolean matcher(HttpServletRequest request, Plugin plugin) {
        return matcher("loginService",plugin);
    }
}
